Repository navigation
Host client-streaming and bidirectional gRPC methods - #1641
Merged
Merged
Conversation
The server host read the whole request before handing it to the SDK, so GrpcServerAdapter rejected client-streaming and bidirectional methods. Read the request on its own virtual thread instead, handing it to the SDK as it arrives: the handler returns once the response head is ready, so responses stream out while the client still sends, and a bidirectional call exchanges messages both ways over one HTTP/2 stream. Request bytes handed to the SDK but not yet consumed by its deframer, which only reads the messages the application requested, stay within the queue budget, so an unread request pushes back on the client. Message size stays bounded by the SDK's deframer. A request stream that breaks while read now ends the call as CANCELLED, like a peer reset in grpc-netty, and a read stuck after the call ended is still reset. Part of #1561 (R6a). Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Jerome Louvel <[email protected]>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Critical concurrency bugs can leave response writes blocked beyond deadlines and misinterpret local request-body closure as a failure, cancelling bidirectional calls and releasing admission before delivery completes.
2 open issues
What changed in this PR
Extends experimental gRPC server hosting to client-streaming and bidirectional methods, advancing #1561 while leaving the client adapter unary-only.
Changes:
- Reads requests on a separate virtual thread with demand-driven inbound queue limits.
- Allows all known method types and updates streaming support documentation.
- Adds interoperability tests for streaming, backpressure, large messages, and cancellation.
| File | Description |
|---|---|
readme.md |
Updates supported gRPC modes and remaining client work. |
org.restlet.ext.grpc/src/test/java/org/restlet/ext/grpc/GrpcServerAdapterTestCase.java |
Adds streaming tests and adjusts read-error and reset expectations. |
org.restlet.ext.grpc/src/main/java/org/restlet/ext/grpc/internal/RestletServerHost.java |
Adds asynchronous request reading and inbound byte accounting. |
org.restlet.ext.grpc/src/main/java/org/restlet/ext/grpc/GrpcServerAdapter.java |
Accepts streaming methods and documents per-direction queue limits. |
changes.md |
Records expanded server streaming support and flow control. |
Review effort: Balanced
…lose The request reader and the response writer now run concurrently but shared one in-progress marker, so a read ending while a response write was stuck cleared the writer's marker, and a later deadline or shutdown no longer reset that write. Track reads and writes separately, and reset the stream if either stays stuck after the call ended. When a bidirectional service finishes before the client half-closes, the Netty server closes the unread request body after the terminal write, and the reader took that for a peer failure, cancelling a completed call before its delivery. Ignore read failures once the response ended; the delivery and disconnect signals settle the call. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Jerome Louvel <[email protected]>
The request reader caught InterruptedException without restoring the thread's interrupt status (SonarCloud S2142). Restore it before cancelling the call, and do the same in a test helper. Comment the listener methods the tests don't use, and use unnamed catch variables. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Jerome Louvel <[email protected]>
|
This was referenced Nov 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




First step of R6a (#1561):
GrpcServerAdapterhosts client-streaming and bidirectional methods, so services of every streaming type now run on Restlet. Streaming inGrpcClientAdapterfollows in a separate PR.Change
RestletServerHostread the whole request (at most one message) before handing it to the SDK, sostart()rejected client-streaming and bidirectional methods. Now:setMaxQueuedBytes.bytesRead.setMaxMessageBytes,RESOURCE_EXHAUSTED).setMaxQueuedBytesnow documents that it applies to each direction.CANCELLED, as grpc-netty reports a peer reset; it wasINVALID_ARGUMENT.start()now only rejects methods of typeUNKNOWN.changes.md,readme.mdand the adapter Javadoc are updated.Tests
GrpcServerAdapterTestCaseuses grpc-java's own Netty client over h2c. The new tests are:clientStreamingReceivesEveryMessagebidirectionalCallsExchangeMessagesBothWaysunrequestedMessagesPushBackOnTheClientmessagesLargerThanTheQueueBudgetStreamThroughcancellingAStreamingCallReleasesItsSlotonCanceland frees the only slotunknownMethodTypesFailExplicitlyTwo existing tests were adjusted for the reader thread:
stalledRequestBodyIsResetAtTheDeadlinewaits for the reset rather than asserting it before the handler returns.unreadableRequestStillSendsItsGrpcStatusnow expectsCANCELLED.mvn -o verify -pl org.restlet.ext.grpcpasses: 75 tests. The 74 tests before the last one passed three runs in a row.Not in this PR
GrpcClientAdapter, which is still unary-only.🤖 Generated with Claude Code